local frames = {
	Down = {
		{ Frame=0,	Delay=SRT.SleepDuration},
		{ Frame=1,	Delay=SRT.SleepDuration},
		{ Frame=2,	Delay=SRT.SleepDuration},
		{ Frame=3,	Delay=SRT.SleepDuration}
	},
	Left = {
		{ Frame=4,	Delay=SRT.SleepDuration},
		{ Frame=5,	Delay=SRT.SleepDuration},
		{ Frame=6,	Delay=SRT.SleepDuration},
		{ Frame=7,	Delay=SRT.SleepDuration}
	},
	Right = {
		{ Frame=8,	Delay=SRT.SleepDuration},
		{ Frame=9,	Delay=SRT.SleepDuration},
		{ Frame=10,	Delay=SRT.SleepDuration},
		{ Frame=11,	Delay=SRT.SleepDuration}
	},
	Up = {
		{ Frame=12,	Delay=SRT.SleepDuration},
		{ Frame=13,	Delay=SRT.SleepDuration},
		{ Frame=14,	Delay=SRT.SleepDuration},
		{ Frame=15,	Delay=SRT.SleepDuration}
	}
}

local WillCollide = function()
	local r = false
	local NextTile

	if SRT.Player.dir == "Up" then
		NextTile = (SRT.Player.pos.d-1) * SRT.TileData.Width.Tiles + SRT.Player.pos.r + 1

	elseif SRT.Player.dir == "Down" then
		NextTile = (SRT.Player.pos.d+1) * SRT.TileData.Width.Tiles + SRT.Player.pos.r + 1

	elseif SRT.Player.dir == "Left" then
		NextTile = SRT.Player.pos.d * SRT.TileData.Width.Tiles + SRT.Player.pos.r

	elseif SRT.Player.dir == "Right" then
		NextTile = SRT.Player.pos.d * SRT.TileData.Width.Tiles + SRT.Player.pos.r + 2
	end

	if NextTile then
		if SRT.TileData.CollisionTiles[ NextTile ] == 1 then
			r = true
		elseif SRT.TileData.EventTiles[ NextTile ] ~= 0 then
			TouchHandler( NextTile )
			r = false
		end
	end

	return r
end

local WillBeOffMap = function()
	local r = true

	if SRT.Player.dir == "Up" then
		r = SRT.Player.pos.d > 0
	elseif SRT.Player.dir == "Down" then
		r = SRT.Player.pos.d < SRT.TileData.Height.Tiles-1
	elseif SRT.Player.dir == "Left" then
		r = SRT.Player.pos.r > 0
	elseif SRT.Player.dir == "Right" then
		r = SRT.Player.pos.r < SRT.TileData.Width.Tiles-1
	end

	return not r
end

local UpdatePosition = function()

	-- set the player sprite's current tile to "not collidable"
	-- we are about to update the player sprite's position
	SRT.TileData.CollisionTiles[SRT.Player.pos.d * SRT.TileData.Width.Tiles + SRT.Player.pos.r + 1] = 0

	-- Increment/Decrement the value as needed first
	if SRT.Player.dir == "Up" then
		SRT.Player.pos.d = SRT.Player.pos.d - 1

	elseif SRT.Player.dir == "Down" then
		SRT.Player.pos.d = SRT.Player.pos.d + 1

	elseif SRT.Player.dir == "Left" then
		SRT.Player.pos.r = SRT.Player.pos.r - 1

	elseif SRT.Player.dir == "Right" then
		SRT.Player.pos.r = SRT.Player.pos.r + 1
	end

	-- update this sprite's z value based on its down value
	SRT.Player.pos.z = SRT.TileData.Height.Tiles - SRT.Player.pos.d

	-- set the current tile to collidable
	SRT.TileData.CollisionTiles[SRT.Player.pos.d * SRT.TileData.Width.Tiles + SRT.Player.pos.r + 1] = 1
end

----------------------------------------------------------------------------

return Def.Sprite{

	Texture=THEME:GetPathB("Overworld", "overlay/Sprites/" .. SRT.Player.file .. " 4x4.png" ),
	InitCommand=function(self) SRT.PlayerSprite = self end,
	LoadCommand=function(self)
		self:animate(0)

		-- align to left and v-middle
		self:halign(0)
		self:valign(0.5)

		-- initialize the position
		self:x( SRT.Player.pos.r * SRT.TileData.TileSize )
		self:y( SRT.Player.pos.d * SRT.TileData.TileSize )
		self:z( -(SRT.TileData.Height.Tiles - SRT.Player.pos.d) )
		-- initialize the sprite state
		self:SetStateProperties( frames[SRT.Player.dir] )

		-- mark the MapData where the player is standing as collidable
		SRT.TileData.CollisionTiles[SRT.Player.pos.d * SRT.TileData.Width.Tiles + SRT.Player.pos.r + 1] = 1
	end,
	UpdateSpriteFramesCommand=function(self)
		self:SetStateProperties( frames[SRT.Player.dir] )
	end,
	AnimationOnCommand=cmd(animate,1),
	AnimationOffCommand=cmd(animate, 0; setstate, 0),
	TweenCommand=function(self)

		-- this does a good job of mitigating tween overflows resulting from button mashing
		self:stoptweening()

		-- sanity check
		if SRT.Player.dir and SRT.Player.input[ SRT.Player.dir ] then

			self:linear(SRT.SleepDuration)
			self:x(SRT.Player.pos.r * SRT.TileData.TileSize)
			self:y(SRT.Player.pos.d * SRT.TileData.TileSize)
			self:z( -SRT.Player.pos.z )
		end
	end,

	AttemptToTweenCommand=function(self, params)

		self:playcommand("AnimationOn")

		-- Does the player sprite's current direction match the direction
		-- we were just passed from the input handler?
		if SRT.Player.dir ~= params.dir then

			-- if not, update it
			SRT.Player.dir = params.dir
			-- and update the sprite's frames appropriately
			self:playcommand("UpdateSpriteFrames")
		end

		-- collision check the impending tile
		if not SRT.Collisions or not WillCollide() then

			-- don't allow us to go off the map
			if not WillBeOffMap() then

				-- we *probably* want to update the player's map position
				-- UpdatePosition() does just that, if we should
				UpdatePosition()

				-- tween the player sprite
				self:playcommand("Tween")
			end
		end
	end
}